package com.bsg.upm.service;

import java.text.MessageFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bsg.upm.check.BackupStorageCheck;
import com.bsg.upm.check.CheckResult;
import com.bsg.upm.constant.DictTypeConstants;
import com.bsg.upm.constant.OperateDictConstants;
import com.bsg.upm.constant.OperateDictTypeConstants;
import com.bsg.upm.constant.SysConstants;
import com.bsg.upm.dto.BackupStorageDto;
import com.bsg.upm.entity.BackupStorageEntity;
import com.bsg.upm.entity.SiteEntity;
import com.bsg.upm.entity.UserEntity;
import com.bsg.upm.exception.APIException;
import com.bsg.upm.http.RespJson;
import com.bsg.upm.http.RespJsonFactory;
import com.bsg.upm.util.DateUtils;
import com.bsg.upm.util.PrimaryKeyUtils;

/**
 * 备份存储管理业务处理类
 * 
 * @author HCK
 *
 */
@Service
public class BackupStorageService extends BaseService {

	@Resource
	private BackupStorageCheck backupStorageCheck;

	/**
	 * 备份存储查询
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	public RespJson list(Map<String, Object> paramMap) throws APIException {
		try {
			// 结果集
			JSONArray results = new JSONArray();

			// 获取指定条件的备份存储
			List<BackupStorageEntity> backupStorages = backupStorageDao.list(paramMap);

			for (BackupStorageEntity backupStorage : backupStorages) {
				// 构建备份存储展示对象
				BackupStorageDto backupStorageDto = buildShowDto(backupStorage, false);
				results.add(backupStorageDto);
			}

			return RespJsonFactory.buildOK(results);
		} catch (Exception e) {
			logger.error("备份存储查询异常", e);
			throw new APIException("备份存储查询异常:" + e.getMessage());
		}
	}

	/**
	 * 备份存储详情
	 * 
	 * @param backupStorageId
	 *            备份存储编码
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	public RespJson get(String backupStorageId) throws APIException {
		try {
			// 获取指定的备份存储
			BackupStorageEntity backupStorage = backupStorageDao.get(backupStorageId);

			if (backupStorage == null) {
				return RespJsonFactory.build(HttpStatus.SC_GONE, "该备份存储不存在");
			}

			// 构建备份存储展示对象
			BackupStorageDto backupStorageDto = buildShowDto(backupStorage, true);

			return RespJsonFactory.buildOK(backupStorageDto);
		} catch (Exception e) {
			logger.error("备份存储获取异常", e);
			throw new APIException("备份存储获取异常:" + e.getMessage());
		}
	}

	/**
	 * 备份存储新增
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	@Transactional(rollbackFor = APIException.class)
	public RespJson save(Map<String, Object> paramMap) throws APIException {
		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_ADD;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 备份存储新增检查
			CheckResult chkRS = backupStorageCheck.checkSave(paramMap);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			// 构建备份存储对象
			BackupStorageEntity backupStorage = buildBackupStorage(paramMap);
			backupStorageDao.save(backupStorage);

			// MGM备份存储查询条件
			Map<String, Object> nfsParamMap = new HashMap<String, Object>();
			nfsParamMap.put("nfs_ip", backupStorage.getIp());
			nfsParamMap.put("nfs_dir", backupStorage.getDir());
			nfsParamMap.put("nfs_mount_dir", backupStorage.getMountDir());
			nfsParamMap.put("nfs_mount_opts", backupStorage.getMountOpts());
			String siteId = backupStorage.getSite().getId();
			// 从MGM获取备份存储信息
			getNfsBackupSpaceInfoFromMGM(siteId, nfsParamMap);

			// 保存操作日志
			saveOperateLog(OperateDictConstants.MODEL_BACKUP_STORAGE, operateAcion, backupStorage.getId(),
					backupStorage.getName(), backupStorage.getCreateDateTime());

			return RespJsonFactory.buildCreated();
		} catch (Exception e) {
			logger.error("备份存储" + operateAcionText + "异常", e);
			throw new APIException("备份存储" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 备份存储编辑
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	@Transactional(rollbackFor = APIException.class)
	public RespJson update(Map<String, Object> paramMap) throws APIException {
		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_UPDATE;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 备份存储编辑检查
			CheckResult chkRS = backupStorageCheck.checkUpdate(paramMap);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			// 构建备份存储对象
			BackupStorageEntity backupStorage = buildBackupStorageToUpdate(paramMap);
			backupStorageDao.update(backupStorage);

			// 保存操作日志
			saveOperateLog(OperateDictConstants.MODEL_BACKUP_STORAGE, operateAcion, backupStorage.getId(),
					backupStorage.getName());

			return RespJsonFactory.buildOK();
		} catch (Exception e) {
			logger.error("备份存储" + operateAcionText + "异常", e);
			throw new APIException("备份存储" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 备份存储启用/停用
	 * 
	 * @param id
	 *            备份存储编码
	 * @param enable
	 *            是否启用
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	@Transactional(rollbackFor = APIException.class)
	public RespJson enable(String id, boolean enable) throws APIException {
		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_DISABLE;
		if (enable) {
			operateAcion = OperateDictConstants.ACTION_ENABLE;
		}
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 获取指定的备份存储
			BackupStorageEntity backupStorage = backupStorageDao.get(id);

			// 备份存储启停检查
			CheckResult chkRS = null;
			if (enable) {
				chkRS = backupStorageCheck.checkEnable(backupStorage);
			} else {
				chkRS = backupStorageCheck.checkDisable(backupStorage);
			}
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			// 设置启停状态
			backupStorage.setEnabled(enable);
			backupStorageDao.updateEnabled(backupStorage);

			// 保存操作日志
			saveOperateLog(OperateDictConstants.MODEL_BACKUP_STORAGE, operateAcion, backupStorage.getId(),
					backupStorage.getName());

			return RespJsonFactory.buildOK();
		} catch (Exception e) {
			logger.error("备份存储" + operateAcionText + "异常", e);
			throw new APIException("备份存储" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 备份存储删除
	 * 
	 * @param id
	 *            备份存储编码
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	@Transactional(rollbackFor = APIException.class)
	public RespJson remove(String id) throws APIException {
		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_REMOVE;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 获取指定的备份存储
			BackupStorageEntity backupStorage = backupStorageDao.get(id);

			// 备份存储删除检查
			CheckResult chkRS = backupStorageCheck.checkRemove(backupStorage);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			backupStorageDao.remove(id);

			// 保存操作日志
			saveOperateLog(OperateDictConstants.MODEL_BACKUP_STORAGE, operateAcion, backupStorage.getId(),
					backupStorage.getName());

			return RespJsonFactory.buildNoContent();
		} catch (Exception e) {
			logger.error("备份存储" + operateAcionText + "异常", e);
			throw new APIException("备份存储" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 从MGM获取备份存储信息
	 * 
	 * @param siteId
	 *            站点编码
	 * @param paramMap
	 *            备份存储查询条件
	 * @return JSONObject 备份存储信息
	 * @throws APIException
	 *             API异常处理类
	 */
	private JSONObject getNfsBackupSpaceInfoFromMGM(String siteId, Map<String, Object> paramMap) throws APIException {
		String urlPattern = "/{0}/nfs_backups/space?nfs_ip={1}&nfs_dir={2}&nfs_mount_dir={3}&&nfs_mount_opts={4}";
		String url = MessageFormat.format(urlPattern, SysConstants.MGM_VERSION, paramMap.get("nfs_ip"),
				paramMap.get("nfs_dir"), paramMap.get("nfs_mount_dir"), paramMap.get("nfs_mount_opts"));
		RespJson httpRespJson = sendHttpGet(siteId, SysConstants.INTERFACE_TYPE_MGM, url);
		if (httpRespJson.getStatus() == HttpStatus.SC_OK) {
			return ((JSONObject) httpRespJson.getData());
		} else {
			throw new APIException(httpRespJson.getMsg());
		}
	}

	/**
	 * 构建备份存储展示对象
	 * 
	 * @param backupStorage
	 *            备份存储对象
	 * @param showDetail
	 *            是否展示详情
	 * @return 备份存储展示
	 * @throws APIException
	 *             API异常处理类
	 */
	private BackupStorageDto buildShowDto(BackupStorageEntity backupStorage, boolean showDetail) throws APIException {
		BackupStorageDto backupStorageDto = new BackupStorageDto();
		SiteEntity site = backupStorage.getSite();
		backupStorageDto.setSiteId(site.getId());
		backupStorageDto.setSiteName(site.getName());
		backupStorageDto.setId(backupStorage.getId());
		backupStorageDto.setName(backupStorage.getName());
		backupStorageDto.setType(backupStorage.getType());
		backupStorageDto.setTypeText(
				dictTypeCache.getTextFromCache(DictTypeConstants.BACKUP_STORAGE_TYPE, backupStorage.getType()));
		backupStorageDto.setEnabled(backupStorage.getEnabled());
		backupStorageDto.setEnabledText(dictTypeCache.getTextFromCache(DictTypeConstants.STATUS_ENABLED,
				String.valueOf(backupStorage.getEnabled())));
		backupStorageDto.setIp(backupStorage.getIp());
		backupStorageDto.setDir(backupStorage.getDir());
		backupStorageDto.setMountDir(backupStorage.getMountDir());
		backupStorageDto.setMountOpts(backupStorage.getMountOpts());
		backupStorageDto.setDescription(backupStorage.getDescription());
		backupStorageDto.setCreateDateTime(DateUtils.dateTimeToString(backupStorage.getCreateDateTime()));
		backupStorageDto.setCreateLoginUserName(backupStorage.getCreateUserLoginName());

		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("nfs_ip", backupStorage.getIp());
		paramMap.put("nfs_dir", backupStorage.getDir());
		paramMap.put("nfs_mount_dir", backupStorage.getMountDir());
		paramMap.put("nfs_mount_opts", backupStorage.getMountOpts());
		String siteId = backupStorage.getSite().getId();
		JSONObject nfsBackupSpaceInfo = getNfsBackupSpaceInfoFromMGM(siteId, paramMap);
		if (nfsBackupSpaceInfo != null) {
			backupStorageDto.setTotalSpace(nfsBackupSpaceInfo.getLongValue("total_space"));
			backupStorageDto.setFreeSpace(nfsBackupSpaceInfo.getLongValue("free_space"));
		}
		return backupStorageDto;
	}

	/**
	 * 构建备份存储对象
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return 备份存储对象
	 */
	private BackupStorageEntity buildBackupStorage(Map<String, Object> paramMap) {
		BackupStorageEntity backupStorage = new BackupStorageEntity();
		backupStorage.setId(PrimaryKeyUtils.uniqueId());
		backupStorage.setName(StringUtils.trim((String) paramMap.get("name")));
		backupStorage.setType((String) paramMap.get("type"));
		backupStorage.setIp(StringUtils.trim((String) paramMap.get("ip")));
		backupStorage.setDir(StringUtils.trim((String) paramMap.get("dir")));
		backupStorage.setMountDir(StringUtils.trim((String) paramMap.get("mountDir")));
		backupStorage.setMountOpts(StringUtils.trim((String) paramMap.get("mountOpts")));
		if (paramMap.containsKey("description")) {
			backupStorage.setDescription(StringUtils.trim((String) paramMap.get("description")));
		}
		backupStorage.setEnabled(true);
		backupStorage.setCreateDateTime(systemDao.getCurrentDateTime());
		UserEntity user = getUser();
		String username = user.getUsername();
		backupStorage.setCreateUserLoginName(username);
		SiteEntity site = new SiteEntity();
		site.setId((String) paramMap.get("site"));
		backupStorage.setSite(site);
		return backupStorage;
	}

	/**
	 * 构建备份存储对象用于更新操作
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return 备份存储对象
	 */
	private BackupStorageEntity buildBackupStorageToUpdate(Map<String, Object> paramMap) {
		BackupStorageEntity backupStorage = backupStorageDao.get((String) paramMap.get("backupStorageId"));
		if (paramMap.containsKey("name")) {
			backupStorage.setName(StringUtils.trim((String) paramMap.get("name")));
		}

		if (paramMap.containsKey("description")) {
			backupStorage.setDescription(StringUtils.trim((String) paramMap.get("description")));
		}
		return backupStorage;
	}

}
